﻿namespace wwl.SharedContracts.MultiTenancy;

/// <summary>
/// 提供当前逻辑执行流中的租户上下文信息。
/// </summary>
/// <remarks>
/// <para>
/// - <see cref="TenantId"/> 为 <see langword="null"/> 表示当前操作者为**系统管理员（SystemManager）**。
/// - 使用 <see cref="AsyncLocal{T}"/> 确保在 <c>async/await</c> 调用链中上下文正确传递。
/// - 必须在请求结束时调用 <see cref="Clear"/> 以防止上下文泄露。
/// </para>
/// </remarks>
public static class TenantContextAccessor
{
  private static readonly AsyncLocal<string?> _tenantId = new();
  private static readonly AsyncLocal<bool> _isSystemAdmin = new();

  /// <summary>
  /// 获取或设置当前租户的唯一标识。
  /// </summary>
  /// <value>
  /// 租户 ID；若为 <see langword="null"/>，表示当前为系统管理员。
  /// </value>
  public static string? TenantId
  {
    get => _tenantId.Value;
    set => _tenantId.Value = value;
  }

  /// <summary>
  /// 获取是否为系统管理员。
  /// </summary>
  /// <value>
  /// <see langword="true"/> 表示系统管理员，可访问所有租户数据。
  /// </value>
  public static bool IsSystemAdmin => _isSystemAdmin.Value;

  /// <summary>
  /// 初始化租户上下文。
  /// </summary>
  /// <param name="tenantId">当前租户ID，若为 <see langword="null"/> 则视为系统管理员。</param>
  internal static void SetContext(string? tenantId)
  {
    _tenantId.Value = tenantId;
    _isSystemAdmin.Value = string.IsNullOrEmpty(tenantId);
  }

  /// <summary>
  /// 清除当前上下文，重置为默认值。
  /// </summary>
  public static void Clear()
  {
    _tenantId.Value = null;
    _isSystemAdmin.Value = false;
  }
}